<script setup lang="ts">
import { ref, computed } from 'vue'
import { onShow } from '@dcloudio/uni-app'
import vkDataInputNumberBox from '@/components/vk-data-input-number-box.vue'
import { getSetmealsByIdAPI, getCollectStatusAPI, editStatusAPI } from '@/services/goods'
import type { SetmealsItem, GoodSkuDTO } from '@/types/setmeal'
import type { IcartItem } from '@/types/cart'
import { useCart, useOrder, useMemberStore, useStore } from '@/stores'
const { addCartData } = useCart()
const { addOrderData } = useOrder()
const { getUserInfo, setCollectCount } = useMemberStore()
const { getStoreInfo } = useStore()
const cartMode = ref(1)
const hasSpec = ref(false)
const isCollect = ref(0)

// uni-ui 弹出层组件 ref
const popup = ref<{
  open: (type?: UniHelper.UniPopupType) => void
  close: () => void
}>()
const setmealNumTotal = ref(1)
const setmealCartTotal = ref(0)

// 获取屏幕边界到安全区域距离
const { safeAreaInsets } = uni.getSystemInfoSync()

const currentIndex = ref(0)

// 接收页面参数
const query = defineProps<{
  id: string
}>()

// 商品信息
const goodsInfo = ref({} as SetmealsItem)
const priceRange = computed(() => {
  return '￥' + goodsInfo.value.price
})

onShow(async () => {
  getSetmealsByIdAPI(query.id).then((res) => {
    goodsInfo.value = {
      ...res.data,
      goodSkuList: res.data.goodSkuList.map((item) => {
        return { ...item, num: 0 }
      }),
    }
  })

  const collectRes = await getCollectStatusAPI({
    goodsId: query.id,
    isSetmeal: 1,
    userId: getUserInfo().id,
  })
  isCollect.value = collectRes.data as number
})

const onChange: UniHelper.SwiperOnChange = (ev) => {
  currentIndex.value = ev.detail.current
}

// 点击图片时
const onTapImage = (url: string) => {
  // 大图预览
  uni.previewImage({
    current: url,
    urls: goodsInfo.value.imageLists!.map((item: any) => item.url),
  })
}

const verification = () => {
  if (mainGoodList.value?.length > 0) {
    const mainGoodsTotal = mainGoodList.value.reduce((sum, item) => sum + item.num, 0)
    if (!mainGoodsTotal || mainGoodsTotal < mainLimitNum.value) {
      return '可选漏选'
    }
  }

  if (secondList.value?.length > 0) {
    const secondGoodsTotal = secondList.value.reduce((sum, item) => sum + item.num, 0)
    if (!secondGoodsTotal || secondGoodsTotal < secondLimitNum.value) {
      return '零食漏选'
    }
  }

  if (thridList.value?.length > 0) {
    const thridGoodsTotal = thridList.value.reduce((sum, item) => sum + item.num, 0)
    if (!thridGoodsTotal || thridGoodsTotal < thridLimitNum.value) {
      return '饮料漏选'
    }
  }
  return 'ok'
}

const buyNow = () => {
  // 校验
  const okstr = verification()
  if (okstr !== 'ok') {
    uni.showToast({
      title: okstr, // 提示文字
      duration: 2000, // 显示时长（毫秒）
      icon: 'none', // 图标（可选，默认为 'success'，也可以是 'none'）
      mask: false, // 是否显示透明遮罩层（默认 false）
    })
    return
  }
  console.log('立即购买')
  const orderRecord: IcartItem = getGoodsData()
  addOrderData([orderRecord])
  uni.navigateTo({ url: '/pagesOrder/create/create' })
}

const onCartHandler = () => {
  // 校验
  const okstr = verification()
  if (okstr !== 'ok') {
    uni.showToast({
      title: okstr, // 提示文字
      duration: 2000, // 显示时长（毫秒）
      icon: 'none', // 图标（可选，默认为 'success'，也可以是 'none'）
      mask: false, // 是否显示透明遮罩层（默认 false）
    })
    return
  }

  console.log('加入购物车')

  const cartRecord: IcartItem = getGoodsData()
  addCartData(cartRecord)
}

const getGoodsData = (): IcartItem => {
  // 购物车计算补全
  setmealCartTotal.value = setmealNumTotal.value
  if (setmealNumTotal.value === 0) {
    setmealCartTotal.value = setmealNumTotal.value = 1
  }

  const getItem = (item: GoodSkuDTO): IcartItem => {
    return {
      checked: true,
      id: item._id as number,
      storeId: getStoreInfo()?.storeId,
      goods_id: item.goods_id,
      name: item.goods_name,
      image: item.image,
      description: null,
      specification: item.specification as string,
      price: item.price,
      costPrice: item.cost as number,
      num: item.num,
      hasSku: !item.specification || item.specification == '{}' ? 0 : 1,
      isSetmeal: 0,
      setmealPid: goodsInfo.value.id,
      skuId: item._id as number,
    } as IcartItem
  }
  const desc: IcartItem[] = [
    ...mainGoodList.value
      .filter((item: GoodSkuDTO) => item.num > 0)
      .map((item: GoodSkuDTO) => {
        return getItem(item)
      }),
    ...secondList.value
      .filter((item: GoodSkuDTO) => item.num > 0)
      .map((item: GoodSkuDTO) => {
        return getItem(item)
      }),
    ...thridList.value
      .filter((item: GoodSkuDTO) => item.num > 0)
      .map((item: GoodSkuDTO) => {
        return getItem(item)
      }),
    ...fourList.value.map((item: GoodSkuDTO) => {
      return getItem(item)
    }),
  ]

  const costPrice: number = goodsInfo.value.goodSkuList.reduce(
    (sum, item) => sum + (item.price ? item.price : 0) * (item.num ?? 0),
    0,
  )

  const getUniqueId = () => {
    return goodsInfo.value.id + '_' + desc.reduce((sum, item) => sum + '_' + item.skuId, '')
  }
  // goodsInfo.value.cost,

  // 加入购物车
  const cartRecord: IcartItem = {
    checked: true,
    id: getUniqueId(),
    storeId: getStoreInfo()?.storeId,
    goods_id: goodsInfo.value.id,
    name: goodsInfo.value.name,
    image: goodsInfo.value.imageUrl,
    description: desc.map((item: IcartItem) => item.name + 'x' + item.num).join('\n'),
    price: goodsInfo.value.price,
    costPrice: 0,
    num: setmealCartTotal.value,
    hasSku: 0,
    specification: '',
    isSetmeal: 1,
    setmealPid: null,
    skuId: null,
    subList: desc,
  }
  return cartRecord
}

const mainGoodList = computed(() => {
  return goodsInfo.value.goodSkuList?.filter((item: any) => {
    return item.setmealType === 0
  })
})

const mainLimitNum = computed(() => {
  const arrs: number[] = mainGoodList.value.map((item: any) => item.limitNum)
  return Math.max(...arrs)
})
const secondList = computed(() => {
  return goodsInfo.value.goodSkuList?.filter((item: any) => {
    return item.setmealType === 1
  })
})
const secondLimitNum = computed(() => {
  const arrs: number[] = secondList.value.map((item: any) => item.limitNum)
  return Math.max(...arrs)
})
const thridList = computed(() => {
  return goodsInfo.value.goodSkuList?.filter((item: any) => {
    return item.setmealType === 2
  })
})
const thridLimitNum = computed(() => {
  const arrs: number[] = thridList.value.map((item: any) => item.limitNum)
  return Math.max(...arrs)
})

const fourList = computed(() => {
  return goodsInfo.value.goodSkuList
    ?.filter((item: any) => {
      return item.setmealType === 3
    })
    .map((item: any) => {
      return { ...item, num: 1 }
    })
})

const radioClick = (record: GoodSkuDTO) => {
  goodsInfo.value.goodSkuList = goodsInfo.value.goodSkuList.map((item: GoodSkuDTO) => {
    if (item.setmealType === record.setmealType) {
      if (item._id === record._id) {
        const bol = !record.radioCheckedBol
        const num = bol ? 1 : 0
        return { ...item, num, radioCheckedBol: bol }
      } else {
        return { ...item, num: 0, radioCheckedBol: false }
      }
    }

    return item
  })
}

const numOnChange = (numItem: any) => {
  setmealNumTotal.value = numItem.value

  if (setmealCartTotal.value > 0) {
    setmealCartTotal.value = setmealNumTotal.value
  }
}

const numChange = (numItem: any, record: GoodSkuDTO) => {
  let arrs: GoodSkuDTO[] = goodsInfo.value.goodSkuList
  let arrList: GoodSkuDTO[] = goodsInfo.value.goodSkuList.filter((fitem: any) => {
    return fitem.setmealType == record.setmealType
  })
  for (let i = 0; i < arrList?.length; i++) {
    let item = arrList[i]
    if (item._id === record._id) {
      const sum = arrList.reduce((sum, item: any) => sum + item.num, 0) // 累加 num
      if (sum > item.limitNum) {
        let m = i - 1
        m = m < 0 ? arrList?.length - 1 : m
        for (let j = m; j > -1; j--) {
          if (arrList[j].num > 0) {
            arrList[j] = { ...arrList[j], num: arrList[j].num - 1 }
            break
          } else {
            if (j === 0) {
              for (let j = arrList?.length - 1; j > -1; j--) {
                if (i !== j && arrList[j].num > 0) {
                  arrList[j] = { ...arrList[j], num: arrList[j].num - 1 }
                  break
                }
              }
            }
          }
        }
      }
      arrList[i] = { ...item, num: numItem.value }
    }
  }

  goodsInfo.value.goodSkuList = arrs.map((item: GoodSkuDTO) => {
    if (item.setmealType === record.setmealType) {
      const re: GoodSkuDTO = arrList.find((aItem: GoodSkuDTO) => {
        return aItem._id === item._id
      }) as GoodSkuDTO
      return { ...item, num: re?.num }
    }
    return item
  })
}

const editStatuhandle = async () => {
  const isCollectValue = isCollect.value === 1 ? 0 : 1
  await editStatusAPI({
    goodsId: query.id,
    isSetmeal: 1,
    userId: getUserInfo().id,
    collectStatus: isCollectValue,
  })

  isCollect.value = isCollectValue
  setCollectCount(1, isCollectValue === 1)
}
</script>

<template>
  <view class="good-container">
    <scroll-view scroll-y class="viewport">
      <!-- 基本信息 -->
      <view class="goods">
        <!-- 商品主图 -->
        <view class="preview">
          <swiper @change="onChange" circular>
            <swiper-item
              @tap="onTapImage(item.url)"
              v-for="item in goodsInfo.imageLists"
              :key="item.imageId"
            >
              <image mode="aspectFill" :src="item.url" />
            </swiper-item>
          </swiper>
          <view class="indicator">
            <text class="current">{{ currentIndex + 1 }}</text>
            <text class="split">/</text>
            <text class="total">{{ goodsInfo.imageLists?.length || 0 }}</text>
          </view>

          <view class="heart" @click="editStatuhandle">
            <text class="icon-heart" :class="{ active: isCollect === 1 }"></text>
          </view>
        </view>

        <!-- 商品名称+价格 -->
        <view class="meta">
          <view class="name ellipsis">{{ goodsInfo.name }}</view>
          <view class="info ellipsis">
            <rich-text :nodes="goodsInfo.description"></rich-text>
          </view>
          <view class="price">
            <text class="symbol">{{ priceRange }}</text>
            <!-- <text class="acount">{{ 234.8 }}</text> -->
            <view class="right">
              <vk-data-input-number-box
                v-model="setmealNumTotal"
                :min="0"
                :max="50"
                :step="1"
                :step-strictly="true"
                :disabled="false"
                :disabled-input="false"
                :cursor-spacing="100"
                :long-press="true"
                :press-time="250"
                :positive-integer="true"
                @change="numOnChange"
              ></vk-data-input-number-box>
            </view>
          </view>
        </view>
        <!-- 主菜 -->
        <view class="setmeal-goods-wrap" v-if="mainGoodList?.length > 0">
          <view class="setmeal-goods-title">可选 （任选{{ mainLimitNum }}）</view>
          <view class="setmeal-goods-list">
            <view
              :class="['setmeal-goods-item', item.num > 0 ? 'actived' : '']"
              v-for="item in mainGoodList"
              :key="item._id"
              @click="numChange({ value: 1 }, item)"
            >
              <view class="inner">
                <image class="img" :src="item.image" mode="scaleToFill" />
                <view class="title">{{ item.goods_name }}</view>
                <vk-data-input-number-box
                  v-model="item.num"
                  :min="0"
                  :max="item.limitNum"
                  :step="1"
                  :step-strictly="true"
                  :disabled="false"
                  :disabled-input="false"
                  :cursor-spacing="100"
                  :long-press="true"
                  :press-time="250"
                  :positive-integer="true"
                  @change="(numItem:any) => numChange(numItem, item)"
                ></vk-data-input-number-box>
              </view>
            </view>
          </view>
        </view>
        <!-- 零食 -->
        <view class="setmeal-goods-wrap" v-if="secondList?.length > 0">
          <view class="setmeal-goods-title">可选（任选{{ secondLimitNum }}）</view>
          <view class="setmeal-goods-list">
            <view
              :class="['setmeal-goods-item', item.num > 0 ? 'actived' : '']"
              v-for="item in secondList"
              :key="item._id"
              @click="numChange({ value: 1 }, item)"
            >
              <view class="inner">
                <image class="img" :src="item.image" mode="scaleToFill" />
                <view class="title">{{ item.goods_name }}</view>
                <vk-data-input-number-box
                  :v-model="item.num"
                  :min="0"
                  :max="item.limitNum"
                  :step="1"
                  :step-strictly="true"
                  :disabled="false"
                  :disabled-input="false"
                  :cursor-spacing="100"
                  :long-press="true"
                  :press-time="250"
                  :positive-integer="true"
                  @change="(numItem:any) => numChange(numItem, item)"
                ></vk-data-input-number-box>
              </view>
            </view>
          </view>
        </view>
        <!-- 饮品 -->
        <view class="setmeal-goods-wrap" v-if="thridList?.length > 0">
          <view class="setmeal-goods-title">饮品可选（任选{{ thridLimitNum }}）</view>
          <view class="setmeal-goods-list">
            <view
              :class="['setmeal-goods-item', item.radioCheckedBol ? 'actived' : '']"
              v-for="item in thridList"
              :key="item._id"
              @click.stop="radioClick(item)"
            >
              <view class="inner">
                <image class="img" :src="item.image" mode="scaleToFill" />
                <view class="title">{{ item.goods_name }}</view>

                <view class="radio-wrapper">
                  <view @click.stop="radioClick(item)" class="radio-item">
                    <text
                      class="iconfont icon-gouxuan-xuanzhong-yuankuang"
                      v-if="item.radioCheckedBol"
                    ></text>
                    <text class="iconfont icon-gouxuan3" v-else></text>
                  </view>
                </view>
              </view>
            </view>
          </view>
        </view>
        <!-- 已选 -->
        <view class="setmeal-goods-wrap" v-if="fourList?.length > 0">
          <view class="setmeal-goods-title">已选</view>
          <view class="setmeal-goods-list">
            <view class="setmeal-goods-item actived" v-for="item in fourList" :key="item._id">
              <view class="inner">
                <image class="img" :src="item.image" mode="scaleToFill" />
                <view class="title">{{ item.goods_name }}</view>
              </view>
            </view>
          </view>
        </view>
      </view>
    </scroll-view>

    <!-- 用户操作 -->
    <view class="toolbar" :style="{ paddingBottom: safeAreaInsets?.bottom + 'px' }">
      <navigator class="icons-button" url="/pages/cart/cart" open-type="switchTab">
        <text class="iconfont icon-cart-add"></text>
        <text class="tag" v-if="setmealCartTotal">+{{ setmealCartTotal }}</text>
      </navigator>
      <view class="addcart" @tap="onCartHandler()"> 加入购物车 </view>
      <view class="buynow" @tap="buyNow()"> 立即购买 </view>
    </view>
  </view>
</template>

<style lang="scss">
@import '@/styles/variables.scss';
page {
  height: 100%;
  overflow: hidden;
  display: flex;
  flex-direction: column;
}
.good-container {
  display: flex;
  flex-direction: column;
  height: 100%;
}

.radio-wrapper {
  display: flex;
  flex-direction: row;
  justify-content: flex-end;
  width: 100%;
  .iconfont {
    color: #4caf50;
    font-size: 50rpx;
  }
}
.setmeal-goods-wrap {
  .setmeal-goods-title {
    padding: 0 30rpx;
    font-size: $font-size;
    color: $font-title-color;
  }
  .setmeal-goods-list {
    display: flex;
    flex-direction: row;
    flex-wrap: wrap;
    padding: 18rpx;
    // row-gap: 40rpx;
    .setmeal-goods-item {
      width: 33.33%;
      padding: 14rpx;
      .inner {
        display: flex;
        flex-direction: column;
        align-items: center;
        border-width: 1px; // 粗细
        border-style: solid; // 样式（实线、虚线等）
        border-color: #e2e1e1;
        padding: 20rpx;
        border-radius: $border-medium-radius;
        .img {
          width: 100%;
          height: 200rpx;
        }
        .title {
          font-size: $font-size;
          padding: 10rpx 0;
          @include lines-ellipsis-style(2);
        }
      }
      &.actived {
        .inner {
          border-width: 1px; // 粗细
          border-style: solid; // 样式（实线、虚线等）
          border-color: $color; // 颜色
        }
      }
    }
  }
}

.viewport {
  background-color: #f9fafb;
  flex: 1;
  padding-bottom: 50rpx;

  .goods {
    .preview {
      height: 686rpx;
      position: relative;
      .image {
        width: 750rpx;
        height: 750rpx;
      }
      .indicator {
        box-sizing: border-box;
        padding: 0 24rpx;
        line-height: 56rpx;
        border-radius: 28rpx;
        color: #fff;
        font-size: $font-size;
        font-weight: $font-regular-weight;
        background-color: rgba(0, 0, 0, 0.4);
        position: absolute;
        bottom: 30rpx;
        right: 30rpx;
      }
      .heart {
        box-sizing: border-box;
        // padding: 0 24rpx;
        position: absolute;
        top: 30rpx;
        right: 30rpx;
        border-radius: 50%;
        background-color: rgba(255, 255, 255, 0.8);
        width: 46rpx;
        height: 46rpx;
        display: flex;
        align-items: center;
        justify-content: center;
        .icon-heart {
          &::before {
            content: '\e708';
            font-family: 'iconfont' !important;
            color: #ccc;
            font-size: 40rpx;
          }
        }

        .icon-heart {
          &.active {
            &::before {
              color: $price-font-color;
              content: '\e708';
              font-family: 'iconfont' !important;
              font-size: 40rpx;
            }
          }
        }
      }
    }
    .meta {
      padding: $lager-padding;
      border-radius: $border-lager-radius;
      display: flex;
      flex-direction: column;
      background-color: #fff;

      margin: $medium-padding 0;
      // align-items: center;
      // justify-content: space-between;
      .name {
        color: $good-font-title-color;
        font-size: $font-largex-size;
        font-weight: $font-bold-weight;
      }
      .info {
        color: $font-color;
        font-size: $font-size;
        margin-top: 12rpx;
        margin-bottom: 12rpx;
      }
      .price {
        display: flex;
        flex-direction: row;
        align-items: center;
        justify-content: space-between;
        .symbol {
          font-size: $font-largexx-size;
          color: $price-font-color;
          font-weight: $font-bold-weight;
        }
        .acount {
          margin-left: $smallx-padding;
          font-size: $font-size;
          color: $good-font-con-color;
          font-weight: $font-weight;
          text-decoration: line-through;
        }
      }
    }
    .info-detail {
      padding: $lager-padding;
      border-radius: $border-lager-radius;
      display: flex;
      flex-direction: column;
      background-color: #fff;
      margin: $medium-padding 0;
      .title {
        color: $good-font-title-color;
        font-size: $font-largex-size;
        font-weight: $font-bold-weight;
      }

      .desc {
        margin: 12rpx 0;
        color: $font-color;
        font-size: $font-size;
        font-weight: $font-regular-weight;
        line-height: 1.5;
        text-align: justify;
      }
    }
    .instructions {
      margin: 30rpx 0;
      padding: 0 60rpx;
      color: #909090;
      font-size: 28rpx;
      line-height: 1.5;
      text-align: justify;
    }

    .spec {
      padding: $lager-padding;
      border-radius: $border-lager-radius;
      display: flex;
      flex-direction: row;
      background-color: #fff;
      margin: $medium-padding 0;
      justify-content: space-between;
      align-items: center;
      .left {
        display: flex;
        flex-direction: row;
        .spec-name {
          color: $font-color;
          font-size: $font-medium-size;
          font-weight: $font-regular-weight;
          line-height: 1.5;
          margin-right: 10rpx;
        }
        .spec-info {
          color: $good-font-con-color;
          font-size: $font-size;
          font-weight: $font-regular-weight;
          display: flex;
          flex-direction: column;
        }
      }
      .right {
        color: $color;
        font-size: $font-largex-size;
        font-weight: $font-bold-weight;
      }
    }

    .opeate-number {
      padding: $lager-padding;
      border-radius: $border-lager-radius;
      display: flex;
      flex-direction: row;
      background-color: #fff;
      margin: $medium-padding 0;
      justify-content: space-between;
      align-items: center;
      .left {
        .name {
          color: $font-color;
          font-size: $font-medium-size;
          font-weight: $font-regular-weight;
        }
      }
      .right {
      }
    }
  }

  /* 商品详情 */
  .detail {
    padding-left: 20rpx;
    .content {
      margin-left: -20rpx;
      .image {
        width: 100%;
      }
    }
    .properties {
      padding: 0 20rpx;
      margin-bottom: 30rpx;
      .item {
        display: flex;
        line-height: 2;
        padding: 10rpx;
        font-size: 26rpx;
        color: #333;
        border-bottom: 1rpx dashed #ccc;
      }
      .label {
        width: 200rpx;
      }
      .value {
        flex: 1;
      }
    }
  }
}

/* 底部工具栏 */
.toolbar {
  background-color: #fff;
  height: 138rpx;
  padding: 0 20rpx var(--window-bottom);
  border-top: 1rpx solid $border-color;
  display: flex;
  justify-content: space-between;
  align-items: center;
  box-sizing: content-box;
  flex-direction: row;

  .buynow,
  .addcart {
    width: 290rpx;
    height: 88rpx;

    background-color: $color;
    color: #fff;
    font-size: $font-medium-size;
    font-weight: $font-medium-weight;
    border-radius: 44rpx;
    // margin-left: 20rpx;

    line-height: 88rpx;
    text-align: center;
  }
  .buynow {
    background-color: $red-color;
    margin-left: 20rpx;
  }
  .icons-button {
    margin-right: 40rpx;
    margin-left: 10rpx;
    position: relative;
    .iconfont {
      font-size: 60rpx;
      color: $font-color;
    }
    .tag {
      position: absolute;
      right: -23rpx;
      top: -24rpx;
      max-width: 60rpx;
      max-height: 30rpx;
      min-width: 30rpx;
      min-height: 30rpx;
      background-color: #fa5151;
      padding: 8rpx;
      border-radius: 50%;
      color: #fff;
      text-align: center;
      line-height: 30rpx;
      border: 1px solid #fff4ed;
      font-size: $font-small-size;
    }
    .icon-cart {
      display: block;
      font-size: 60rpx;
      color: $font-color;
    }
  }
}
</style>
